package com.yanx.system.web.api;

import com.yanx.common.annotation.ApiResult;
import com.yanx.common.annotation.OperationLog;
import com.yanx.common.annotation.Pagination;
import com.yanx.common.core.api.BaseApi;
import com.yanx.common.enums.BusinessType;
import com.yanx.common.security.preauthorize.PreAuthorize;
import com.yanx.system.base.command.SysRoleUpdateCmd;
import com.yanx.system.base.model.dto.SysRoleDto;
import com.yanx.system.base.model.qo.SysRoleQo;
import com.yanx.system.base.model.qo.SysUserRoleQo;
import com.yanx.system.base.model.vo.SysRoleVo;
import com.yanx.system.base.model.vo.SysUserVo;
import com.yanx.system.base.query.SysRoleByIdQry;
import com.yanx.system.base.query.SysRoleListQry;
import com.yanx.system.web.command.*;
import com.yanx.system.web.command.check.RoleAllowedCheckCmd;
import com.yanx.system.web.command.check.RoleDataScopeCheckCmd;
import com.yanx.system.web.model.dto.SysRoleUserIdDto;
import com.yanx.system.web.query.DeptListByRoleIdQry;
import com.yanx.system.web.query.SysDeptTreeListQry;
import com.yanx.system.web.query.SysUserAllocatedListQry;
import com.yanx.system.web.query.SysUserUnallocatedListQry;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 角色信息 接口
 *
 * @author: gotanks
 * @create: 2023-5-22
 */
@Tag(name = "角色信息", description = "角色信息")
@RestController
@RequestMapping(value = "/system/role")
public class SystemRoleApi extends BaseApi {

    @PreAuthorize(hasPermi = "system:role:list")
    @Pagination(total = true)
    @ApiResult
    @Operation(summary = "获取角色信息列表")
    @GetMapping("/list")
    public List<SysRoleVo> list(SysRoleQo sysRoleQo) {
        return queryExecutor.execute(new SysRoleListQry(sysRoleQo));
    }
//
//    @Log(title = "角色管理", businessType = BusinessType.EXPORT)
//    @PreAuthorize("@ss.hasPermi('system:role:export')")
//    @PostMapping("/export")
//    public void export(HttpServletResponse response, SysRole role) {
//        List<SysRole> list = roleService.selectRoleList(role);
//        ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
//        util.exportExcel(response, list, "角色数据");
//    }
//

    /**
     * 根据角色编号获取详细信息
     */
    @PreAuthorize(hasPermi = "system:role:query")
    @ApiResult
    @Operation(summary = "根据角色编号获取详细信息")
    @GetMapping("/{roleId}")
    public SysRoleVo getInfo(@PathVariable Long roleId) {
        commandExecutor.execute(new RoleDataScopeCheckCmd(roleId));
        return queryExecutor.execute(new SysRoleByIdQry(roleId));
    }

    /**
     * 新增角色
     */
    @PreAuthorize(hasPermi = "system:role:add")
    @ApiResult
    @Operation(summary = "新增角色")
    @PostMapping
    public void add(@Validated @RequestBody SysRoleDto role) {
        commandExecutor.execute(new SystemRoleAddCmd(role));
    }

    /**
     * 修改保存角色
     */
    @PreAuthorize(hasPermi = "system:role:edit")
    @OperationLog(title = "角色管理", businessType = BusinessType.UPDATE)
    @ApiResult
    @Operation(summary = "修改保存角色")
    @PutMapping
    public void edit(@Validated @RequestBody SysRoleDto role) {
        commandExecutor.execute(new RoleAllowedCheckCmd(role.getId()))
                .execute(new RoleDataScopeCheckCmd(role.getId()))
                .execute(new SystemRoleEditCmd(role));
    }

    /**
     * 修改保存数据权限
     */
    @PreAuthorize(hasPermi = "system:role:edit")
    @OperationLog(title = "角色管理", businessType = BusinessType.UPDATE)
    @ApiResult
    @Operation(summary = "修改保存数据权限")
    @PutMapping("/dataScope")
    public void dataScope(@RequestBody SysRoleDto role) {
        commandExecutor.execute(new RoleAllowedCheckCmd(role.getId()))
                .execute(new RoleDataScopeCheckCmd(role.getId()))
                .execute(new SysRoleUpdateCmd(role.getId(), role));
    }

    /**
     * 状态修改
     */
    @PreAuthorize(hasPermi = "system:role:edit")
    @OperationLog(title = "角色管理", businessType = BusinessType.UPDATE)
    @ApiResult
    @Operation(summary = "状态修改")
    @PutMapping("/changeStatus")
    public void changeStatus(@RequestBody SysRoleDto role) {
        commandExecutor.execute(new RoleAllowedCheckCmd(role.getId()))
                .execute(new RoleDataScopeCheckCmd(role.getId()))
                .execute(new SysRoleUpdateCmd(role.getId(), role));
    }

    /**
     * 删除角色
     */
    @PreAuthorize(hasPermi = "system:role:remove")
    @OperationLog(title = "角色管理", businessType = BusinessType.DELETE)
    @ApiResult
    @Operation(summary = "删除角色")
    @DeleteMapping("/{roleIds}")
    public void remove(@PathVariable Set<Long> roleIds) {
        for (Long roleId : roleIds) {
            commandExecutor.execute(new RoleAllowedCheckCmd(roleId))
                    .execute(new RoleDataScopeCheckCmd(roleId));
        }
        commandExecutor.execute(new SystemRoleRemoveCmd(roleIds));
    }

    /**
     * 获取角色选择框列表
     */
    @PreAuthorize(hasPermi = "system:role:query")
    @ApiResult
    @Operation(summary = "获取角色选择框列表")
    @GetMapping("/optionselect")
    public List<SysRoleVo> optionselect() {
        return queryExecutor.execute(new SysRoleListQry(new SysRoleQo()));
    }

    /**
     * 查询已分配用户角色列表
     */
    @PreAuthorize(hasPermi = "system:role:list")
    @Pagination(total = true)
    @ApiResult
    @Operation(summary = "查询已分配用户角色列表")
    @GetMapping("/authUser/allocatedList")
    public List<SysUserVo> allocatedList(SysUserRoleQo user) {
        return queryExecutor.execute(new SysUserAllocatedListQry(user));
    }

    /**
     * 查询未分配用户角色列表
     */
    @PreAuthorize(hasPermi = "system:role:list")
    @Pagination(total = true)
    @ApiResult
    @Operation(summary = "查询未分配用户角色列表")
    @GetMapping("/authUser/unallocatedList")
    public List<SysUserVo> unallocatedList(SysUserRoleQo user) {
        return queryExecutor.execute(new SysUserUnallocatedListQry(user));
    }

    /**
     * 取消授权用户
     */
    @PreAuthorize(hasPermi = "system:role:edit")
    @OperationLog(title = "角色管理", businessType = BusinessType.GRANT)
    @ApiResult
    @Operation(summary = "取消授权用户")
    @PutMapping("/authUser/cancel")
    public void cancelAuthUser(@RequestBody SysRoleUserIdDto sysRoleUserIdDto) {
        commandExecutor.execute(new SystemUserRoleRemoveCmd(sysRoleUserIdDto.getRoleId(), new Long[]{sysRoleUserIdDto.getUserId()}));
    }

    /**
     * 批量取消授权用户
     */
    @PreAuthorize(hasPermi = "system:role:edit")
    @OperationLog(title = "角色管理", businessType = BusinessType.GRANT)
    @ApiResult
    @Operation(summary = "批量取消授权用户")
    @PutMapping("/authUser/cancelAll")
    public void cancelAuthUserAll(Long roleId, Long[] userIds) {
        commandExecutor.execute(new SystemUserRoleRemoveCmd(roleId, userIds));
    }

    /**
     * 批量选择用户授权
     */
    @PreAuthorize(hasPermi = "system:role:edit")
    @OperationLog(title = "角色管理", businessType = BusinessType.GRANT)
    @ApiResult
    @Operation(summary = "批量选择用户授权")
    @PutMapping("/authUser/selectAll")
    public void selectAuthUserAll(Long roleId, Long[] userIds) {
        commandExecutor.execute(new RoleDataScopeCheckCmd(roleId))
                .execute(new SystemRoleUserAddCmd(roleId, userIds));
    }

    /**
     * 获取对应角色部门树列表
     */
    @PreAuthorize(hasPermi = "system:role:query")
    @ApiResult
    @Operation(summary = "获取对应角色部门树列表")
    @GetMapping(value = "/deptTree/{roleId}")
    public Map<String, Object> deptTree(@PathVariable("roleId") Long roleId) {
        Map<String, Object> result = new HashMap<>();
        result.put("checkedKeys", queryExecutor.execute(new DeptListByRoleIdQry(roleId)));
        result.put("depts", queryExecutor.execute(new SysDeptTreeListQry()));
        return result;
    }
}
